iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
SideProject30

初探 Godot系列 第 14

[DAY 14] 角色移動邏輯 (_input, InputEventScreenDrag)

  • 分享至 

  • xImage
  •  

今日目標:增加移動及對應動畫到昨天完成的角色


▍事前準備

開啟昨天儲存的角色場景。

  • 介紹 _input(event)

    void _input(event: InputEvent) virtual

    Called when there is an input event. The input event propagates up through the node tree until a node consumes it.

      這個方法會在 `input` 事件發生時被呼叫。
    
  • 介紹 InputEventScreenDrag

    Represents a screen drag event.

    Stores information about screen drag events. See Node._input().

      這個類別會儲存拖曳資訊。
    

▍出發

  • 撰寫腳本
    1. 在角色根節點 CharacterBody2D 附加腳本,範本選擇 Node
    2. 宣告變數並初始化:指定我們的角色及動畫節點方便後續操作。
    var player: CharacterBody2D
    var player_anime: AnimatedSprite2D
    # Called when the node enters the scene tree for the first time.
    func _ready():
        player = $"."
        player_anime = player.get_node("AnimatedSprite2D")
    
    1. 編輯輸入方法的邏輯
      這次想要做的移動方式和前面的又有些不同,這次想要做到拖曳移動的效果。
      (從黃色位置點擊,拖曳到紅色位置以相對方向移動)
      https://ithelp.ithome.com.tw/upload/images/20230929/20162875Nikis83GGo.png
      首先先開啟 專案 -> 專案設定 -> 一般 -> 輸入裝置 -> 指點 將以滑鼠模擬觸控打勾,方便測試。
      https://ithelp.ithome.com.tw/upload/images/20230929/20162875FuhogEcGMq.png
      偵測輸入事件:
      1.點擊時更新初始位置,紀錄開始拖曳,並開始播放動畫。
      2.放開時重置方向,紀錄結束拖曳,並停止播放動畫。
      3.拖曳時,更新方向向量及動畫。
    # 記錄方向用
    var direction:Vector2
    # 更新是否仍在拖曳狀態
    var dragged:bool = false
    # 紀錄初始位置
    var oriPos: Vector2
    
    func _input(event):
        # 取得點擊事件。
        if event is InputEventScreenTouch:
    
            # 點擊時更新初始位置,紀錄開始拖曳,並開始播放動畫
            if event.is_pressed():
                oriPos = event.position
                dragged = true
                player_anime.play()
    
            # 放開時重置方向,紀錄結束拖曳,並停止播放動畫
            elif event.is_released():
                direction = Vector2.ZERO
                dragged = false
                player_anime.stop()
    
        # 取得拖曳事件,更新動畫。
        if event is InputEventScreenDrag:
            # 將方向標準化
            direction = (event.position - oriPos).normalized()
            # 如果上下的變化量比左右大時使用預設動畫。
            if abs(direction.y) > abs(direction.x):
                player_anime.animation = "default"
            # 否則如果 x 軸方向為正使用右轉動畫。
            elif direction.x > 0:
                player_anime.animation = "turn_right"
            # 否則如果 x 軸方向為負使用左轉動畫。
            elif direction.x < 0:
                player_anime.animation = "turn_left"
    
    1. 將獲得的方向更新到角色上
    # 移動速度
    var speed:float = 5
    
    func _process(delta):
        # 若拖曳則繼續移動
        if dragged:
            player.position += direction*speed
    

▍執行

現在播放時在畫面中拖曳即可移動角色!
Yes

▍完成

完整檔案

extends CharacterBody2D

var direction:Vector2
var speed:float = 5
var dragged:bool = false
var oriPos: Vector2
var player: CharacterBody2D
var player_anime: AnimatedSprite2D

# Called when the node enters the scene tree for the first time.
func _ready():
	player = $"."
	player_anime = player.get_node("AnimatedSprite2D")

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	if dragged:
		player.position += direction*speed

func _input(event):
	
	if event is InputEventScreenTouch:
		
		if event.is_pressed():
			oriPos = event.position
			dragged = true
			player_anime.play()
			
		elif event.is_released():
			direction = Vector2.ZERO
			dragged = false
			player_anime.stop()
			
	if event is InputEventScreenDrag:
		direction = (event.position - oriPos).normalized()
		if abs(direction.y) > abs(direction.x):
			player_anime.animation = "default"
		elif direction.x > 0:
			player_anime.animation = "turn_right"
		elif direction.x < 0:
			player_anime.animation = "turn_left"

:)


上一篇
[DAY 13] 角色建置 (AnimatedSprite2D, SpriteFrames)
下一篇
[DAY 15] 優化移動顯示 Part.1 (_draw, draw_arc, draw_circle)
系列文
初探 Godot30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言